//
// Created on 2025/8/19.
//
// Node APIs are not fully supported. To solve the compilation error of the interface cannot be found,
// please include "napi/native_api.h".
#include "Canvas.h"
#include "Editor.h"
#include "VideoAsset.h"
#include "Timeline.h"

void Canvas::SetCanvasSize(uint32_t height, uint32_t width)
{
    LOGI("Canvas::SetCanvasSize height %{public}d width %{public}d", height, width);
    
    this->height = height; // 这里变量同名了，用this指代成员变量不然赋值不上。
    this->width = width;
    std::shared_ptr<Timeline> timeline = Editor::GetInstance().GetTimeline();
    if (timeline == nullptr) {
        LOGE("Editor::SetCanvasSize timeline is nullptr");
        return;
    }
    
    std::shared_ptr<VideoAsset> mainVideo = timeline->GetMainVideo();
    if (mainVideo == nullptr) {
        LOGE("Editor::SetCanvasSize mainVideo is nullptr");
        return;
    }
    
    if (mainVideo->GetHeight()==0 || mainVideo->GetWidth()==0) {
        LOGE("Editor::SetCanvasSize mainVideo height or width not prepared");
        return;
    }
    
    float ratioVideo;
    float ratioCanvas = (float)width / (float)height;
    uint32_t rotation = mainVideo->GetRotation();
    
    if (rotation == 90 || rotation == 270) {
        // 如果视频有旋转度则交换宽高
        ratioVideo = (float)mainVideo->GetHeight() / (float)mainVideo->GetWidth();
        LOGI("Editor::SetCanvasSize swap video width and height");
    } else {
        ratioVideo = (float)mainVideo->GetWidth() / (float)mainVideo->GetHeight();
    }
   
    LOGI("Editor::SetCanvasSize ratioVideo is %{public}f, ratioCanvas is %{public}f", ratioVideo, ratioCanvas);
    if (ratioVideo <= ratioCanvas) {
        drawableHeight = height;
        drawableWidth = height * ratioVideo;
    } else {
        drawableWidth = width;
        drawableHeight = width / ratioVideo;
    }
    
    LOGI("Editor::SetCanvasSize drawable height %{public}d width %{public}d", 
            drawableHeight, 
            drawableWidth
    );
}

std::vector<std::pair<uint32_t, uint32_t>> Canvas::GetDrawableArea()
{
    LOGI("Canvas::GetDrawableArea.");
    std::vector<std::pair<uint32_t, uint32_t>> res{};
    if (drawableWidth == 0 | drawableHeight == 0) {
        LOGE("Canvas::GetDrawableArea Didnt set canvas,");
        return {};
    }
    
    if (drawableWidth == width) {
        LOGI("Canvas::GetDrawableArea width is same.");
        uint32_t topBorder = (height - drawableHeight)/2;
        uint32_t bottomBorder = (height + drawableHeight)/2;
        LOGI("Canvas::GetDrawableArea width is %{public}d, top border is %{public}d, left border is %{public}d",
             width,
             topBorder,
             bottomBorder
             );
        res.push_back(std::pair<uint32_t, uint32_t>(0, topBorder));
        res.push_back(std::pair<uint32_t, uint32_t>(width, topBorder));
        res.push_back(std::pair<uint32_t, uint32_t>(width, bottomBorder));
        res.push_back(std::pair<uint32_t, uint32_t>(0, bottomBorder));
        realOrigin = std::pair<float, float>{0, topBorder};
        LOGI("Canvas::GetDrawableArea real origin is %{public}d, %{public}d", realOrigin.first, realOrigin.second);
        return res;
    }
    
    if (drawableHeight == height) {
        LOGI("Canvas::GetDrawableArea height is same.");
        uint32_t leftBorder = (width - drawableWidth)/2;
        uint32_t rightBorder = (width + drawableWidth)/2;
        LOGI("Canvas::GetDrawableArea height is %{public}d, left border is %{public}d, right border is %{public}d",
             height,
             leftBorder,
             rightBorder
             );
        res.push_back(std::pair<uint32_t, uint32_t>(leftBorder, 0));
        res.push_back(std::pair<uint32_t, uint32_t>(rightBorder, 0));
        res.push_back(std::pair<uint32_t, uint32_t>(rightBorder, height));
        res.push_back(std::pair<uint32_t, uint32_t>(rightBorder, height));
        realOrigin = std::pair<float, float>{leftBorder, 0};
        LOGI("Canvas::GetDrawableArea real origin is %{public}d, %{public}d", realOrigin.first, realOrigin.second);
        return res;
    }
    
    LOGE("Canvas::GetDrawableArea Invalid drawable area.");
    return {};
}